package com.zxy.rule;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.NacosServiceManager;
import com.alibaba.cloud.nacos.ribbon.ExtendBalancer;
import com.alibaba.cloud.nacos.ribbon.NacosRule;
import com.alibaba.cloud.nacos.ribbon.NacosServer;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.DynamicServerListLoadBalancer;
import com.netflix.loadbalancer.Server;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

//@Component//需要注入，所以需放在组件里
@Slf4j
public class MyRule extends AbstractLoadBalancerRule {

    @Autowired
    private NacosDiscoveryProperties nacosDiscoveryProperties;
//    NacosDiscovery 相关的属性
    @Autowired
    private NacosServiceManager nacosServiceManager;

//    JUC包 AtomicInteger高并发情况下保证原子性的类
    private static AtomicInteger cout  = new AtomicInteger(0);
   @Override
   @SneakyThrows
//   直接帮我们生成异常程序的，简化代码
//   key:default key指的是集群名称
    public Server choose(Object key) {
/*自定义规则流程：1.先找group
       2.通过group找到namingService
       3.通过namingService找到目前相关用的实例
         3.1 实例为空，做出一个报警
         3.2 实例不为空，找到拿出最大和最小权重，通过算法(逢5过)

*/
//            获取集群，然后加载
//            String clusterName = this.nacosDiscoveryProperties.getClusterName();
            String group = this.nacosDiscoveryProperties.getGroup();
            DynamicServerListLoadBalancer loadBalancer = (DynamicServerListLoadBalancer)this.getLoadBalancer();
            String name = loadBalancer.getName();
//                 name 是服务名
            NamingService namingService = this.nacosServiceManager.getNamingService(this.nacosDiscoveryProperties.getNacosProperties());
//           可用的服务列表
            List<Instance> instances = namingService.selectInstances(name, group, true);
            if (CollectionUtils.isEmpty(instances)) {
                log.warn("no instance in service {}", name);
                return null;
            }
//                List<Instance> instancesToChoose = instances;
//                if (StringUtils.isNotBlank(clusterName)) {
//                    List<Instance> sameClusterInstances = (List)instances.stream().filter((instancex) -> {
//                        return Objects.equals(clusterName, instancex.getClusterName());
//                    }).collect(Collectors.toList());
//                    if (!CollectionUtils.isEmpty(sameClusterInstances)) {
//                        instancesToChoose = sameClusterInstances;
//                    } else {
//                        log.warn("A cross-cluster call occurs，name = {}, clusterName = {}, instance = {}", new Object[]{name, clusterName, instances});
//                    }
//                }

       Instance maxInstance = instances.stream().max(Comparator.comparing(Instance::getWeight)).get();
       Instance minInstance = instances.stream().min(Comparator.comparing(Instance::getWeight)).get();

       int count2 = cout.incrementAndGet();
//       数量加1
//       取余
       int mod = count2 % 5;
       if ((mod == 0)) {
           log.debug("count={},mod={},使用min",count2,mod);
           return new NacosServer(minInstance);
       }else {
           log.debug("count={},mod={},使用max",count2,mod);
           return new NacosServer(maxInstance);
       }
    }

    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {
    }
}
